namespace classifier_test
{

class classifier_tester : private noncopyable
{
public:
	struct build_result
	{
		double build_time;
		int data_count;

		build_result();
	};
	struct test_result
	{
		double test_time;
		int errors;
		int data_count;
		vector<discr_value> classifications;
		vector<bool> corrects;

		test_result();
		double get_error_rate() const;
	};

	void serialize(serializer& Serializer);
	const record_scheme& get_scheme() const;
	void set_scheme(const record_scheme& Val);
	classifier* get_base_classifier() const;
	void set_base_classifier(classifier* Val);
	subarray<stream_classifier* const> get_classifiers() const;
	void set_classifiers(subarray<stream_classifier* const> Val);
	void clear_classifiers();
	void add_classifier(stream_classifier* Val);

	void skip(data_stream* Stream, int SkipCount);
	void build(data_stream* Stream, int BuildCount);
	void test(data_stream* Stream, int TestCount);

	const vector<build_result>& get_build_results() const;
	const vector<test_result>& get_test_results() const;
	void write_classifications(FILE* File, int Classifier) const;

private:
	record_scheme Scheme;
	smart_ptr<classifier> BaseClassifier;
	vector<smart_ptr<stream_classifier> > Classifiers;

	vector<build_result> BuildResults;
	vector<test_result> TestResults;

	void test_on(subarray<const stream_record* const> Data, logger::task& LTask);
	void read_records(data_stream* Stream, vector<smart_ptr<stream_record> >& Data, int MaxCount, int LogStart, int LogEnd, logger::task& LTask);
};

}
